#include <iostream>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <cassert>

#include "message.h"
#include <stdio.h>

namespace net_util
{
    bool send_all(int sockfd, const void *data, size_t length)
    {
        const uint8_t *ptr = static_cast<const uint8_t *>(data);
        while (length > 0)
        {
            ssize_t sent = send(sockfd, ptr, length, MSG_NOSIGNAL);
            if (sent < 0)
            {
                if (errno == EINTR)
                    continue; // 处理信号中断
                return false;
            }
            ptr += sent;
            length -= sent;
        }
        return true;
    }
}
int main()
{
    // 配置参数常量
    constexpr const char *SERVER_IP = "127.0.0.1";
    constexpr int SERVER_PORT = 8888;
    constexpr int RECV_TIMEOUT = 5000; // 5秒接收超时

    // 创建socket并连接服务器（保持原有逻辑）
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
    {
        std::cerr << "创建socket失败: " << strerror(errno) << std::endl;
        return EXIT_FAILURE;
    }

    // 设置接收超时
    timeval tv{.tv_sec = RECV_TIMEOUT / 1000,
               .tv_usec = (RECV_TIMEOUT % 1000) * 1000};
    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

    sockaddr_in serv_addr{};
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &serv_addr.sin_addr) <= 0)
    {
        std::cerr << "无效的服务器地址" << std::endl;
        close(sockfd);
        return EXIT_FAILURE;
    }

    if (connect(sockfd, reinterpret_cast<sockaddr *>(&serv_addr), sizeof(serv_addr)) < 0)
    {
        std::cerr << "连接服务器失败: " << strerror(errno) << std::endl;
        close(sockfd);
        return EXIT_FAILURE;
    }

    // 构造协议报文
    try
    {
        // 构造消息体
        json login_body;
        login_body["username"] = "test_user";
        login_body["password"] = "123456";
        const std::string json_str = login_body.dump();

        // 客户端代码修正
        /*
            uint16_t magic;           // 魔数
    uint16_t version;         // 主版本<<8 | 次版本
    uint32_t seq_num;         // 消息序号（网络字节序）
    MessageType msg_type;     // 消息类型
    ContentType content_type; // 内容格式
    uint16_t body_len;        // Body部分长度（不含头）
    uint32_t checksum;        // CRC32校验码（计算时置0）
        */
        MessageHeader header{};
        header.magic = 0x1234;
        header.version = 1 << 8 | 1;
        header.msg_type = MessageType::LOGIN_REQ;
        header.content_type = ContentType::JSON;
        header.seq_num = 1;
        header.body_len = json_str.size();

        // 1. 转换为网络字节序（必须包含所有字段）
        header.hton(); // 确保此函数正确转换 magic (htons)、body_len (htonl) 等字段

        // 2. 清零校验和字段后计算（header 已为网络字节序）
        header.checksum = 0;
        uint32_t computed_crc = compute_checksum(header, reinterpret_cast<const uint8_t *>(json_str.data()), json_str.size());

        // 3. 直接设置校验和字段（无需再次转换）
        header.checksum = htonl(computed_crc);
        printf("headercheak: %u\n", header.checksum);

        // 组装完整报文
        std::vector<uint8_t> packet;
        packet.reserve(sizeof(MessageHeader) + json_str.size());
        packet.insert(packet.end(),
                      reinterpret_cast<uint8_t *>(&header),
                      reinterpret_cast<uint8_t *>(&header) + sizeof(header));
        packet.insert(packet.end(), json_str.begin(), json_str.end());

        // 可靠发送数据
        if (!net_util::send_all(sockfd, packet.data(), packet.size()))
        {
            throw std::runtime_error("发送数据失败: " + std::string(strerror(errno)));
        }
        std::cout << "成功发送" << packet.size() << "字节数据" << std::endl;

        // 接收响应处理
        std::vector<uint8_t> recv_buffer(4096);
        ssize_t total_recv = 0;

        while (true)
        {
            ssize_t recv_len = recv(sockfd,
                                    recv_buffer.data() + total_recv,
                                    recv_buffer.size() - total_recv,
                                    0);
            if (recv_len == 0)
                break; // 连接关闭
            if (recv_len < 0)
            {
                if (errno == EAGAIN || errno == EWOULDBLOCK)
                {
                    throw std::runtime_error("接收超时");
                }
                throw std::runtime_error("接收错误: " + std::string(strerror(errno)));
            }
            total_recv += recv_len;
            if (total_recv >= sizeof(MessageHeader))
            {
                // 此处应添加完整报文解析逻辑
                break;
            }
        }
    }
    catch (const std::exception &e)
    {
        std::cerr << "操作异常: " << e.what() << std::endl;
        close(sockfd);
        return EXIT_FAILURE;
    }

    close(sockfd);
    return EXIT_SUCCESS;
}